using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;

namespace SmartLauncher
{
	static class Program
	{
		//public static BugReportManager BugReport;

		public delegate int AsyncCompareInvokerDelegate(string startPath, bool keepUnchanged);
		private static AsyncCompareInvokerDelegate AsyncCompareInvoker;
		public static IAsyncResult AsyncCompareResult;

		/// <summary>
		/// This is the main entry point of the application.
		/// </summary>
		[STAThread]
		static void Main(string[] args)
		{
			int syncRC;

			// --- Set up the bug report system ------------------------------------
			//	BugReport = new BugReportManager();

			// --- Self-Update Process ---------------------------------------------
			SelfUpdateEngine.Update(Properties.Settings.Default.RepositoryHome);

			// --- Set up the logging system ---------------------------------------
			if ((Properties.Settings.Default.LogEnabled == true) && (ApplicationStartInfo.StartMode == StartModes.Interactive))
			{
				try
				{
					// When a second instance is started, the log file cannot be opened
					// because it seems to be opened exclusively. This case usually 
					// appens when the setting UpdateOnLaunch is set to True.
					FileStreamWithBackup fs = new FileStreamWithBackup(string.Format("{0}.log", Path.GetFileNameWithoutExtension(Environment.GetCommandLineArgs()[0])), Properties.Settings.Default.LogSize * 1024, Properties.Settings.Default.LogRotation, FileMode.Append);
					fs.CanSplitData = false;
					TextWriterTraceListenerWithTime listener = new TextWriterTraceListenerWithTime(fs);
					Trace.AutoFlush = true;
					Trace.Listeners.Add(listener);
				}
				catch
				{
					// Error: we cannot open the log file
				}
			}

			// --- Start SmartLauncher in interactive or silent mode ---------------
			if (ApplicationStartInfo.StartMode == StartModes.Interactive)
			{
				Application.EnableVisualStyles();
				Application.SetCompatibleTextRenderingDefault(false);

				if (ApplicationStartInfo.TargetApplication != null)
				{
					MessageBox.Show(string.Format("The application '{0}' could not be found.", ApplicationStartInfo.TargetApplication), Properties.Settings.Default.ShellHome, MessageBoxButtons.OK, MessageBoxIcon.Warning);
					return;
				}

				// --- If repository must be updated when SmartLauncher is started -------
				if (Properties.Settings.Default.UpdateOnStart == true)
				{
					if ((Properties.Settings.Default.LowConnectivityAsyncUpdate == true) && (SelfUpdateEngine.LowConnectivity == true))
					{
						AsyncCompareInvoker = new AsyncCompareInvokerDelegate(SyncEngine.Compare);
						AsyncCompareResult = AsyncCompareInvoker.BeginInvoke(ApplicationStartInfo.LocalRoot + "\\", true, AsyncCompareCallback, null);
					}
					else
					{
						SplashDialog dlg = new SplashDialog();
						dlg.Show();
						dlg.Refresh();

						syncRC = SyncEngine.Compare(ApplicationStartInfo.LocalRoot + "\\", true);
						if (syncRC > 0)
							SyncEngine.Synchronize(Properties.Settings.Default.AutomaticBackup == CheckState.Checked ? true : false);
						dlg.Close();
					}
				}
				// === Set the icons =================================================
				ShellEngine.Synchronize(ApplicationStartInfo.LocalRoot);

				SingleApplication.Run(new MainForm());
			}
			else
			{
#if !DEBUG
				try
				{
#endif
				syncRC = SyncEngine.Compare(ApplicationStartInfo.TargetApplicationFolder, false);
#if !DEBUG
				}
				catch
				{
					// I/O error --> Skip synchonization
					if (Properties.Settings.Default.SendBugReport == false)
						MessageBox.Show(string.Format("An error occured while updating '{0}'. \n\nPlease contact the helpdesk to get the latest version.", ApplicationStartInfo.TargetApplication), Properties.Settings.Default.ShellHome, MessageBoxButtons.OK, MessageBoxIcon.Warning);
					else
						throw new InvalidOperationException(string.Format("An error occured while updating '{0}'. \n\nPlease contact the helpdesk to get the latest version.", ApplicationStartInfo.TargetApplication));
					syncRC = 0;
				}
#endif
				if (syncRC > 0)
					SyncEngine.Synchronize(false);

				ShellEngine.Synchronize(ApplicationStartInfo.TargetApplicationFolder);

				Process.Start(ApplicationStartInfo.TargetApplication);
			}
		}

		static void AsyncCompareCallback(IAsyncResult result)
		{
			int rc;
			DoUpdateDialog dlg;

			rc = AsyncCompareInvoker.EndInvoke(result);

			if (rc > 0)
			{
				dlg = new DoUpdateDialog();
				dlg.ShowDialog();
			}
			//		AsyncCompareInvoker
			//	if (result.

			//System.Windows.Forms.Application.OpenForms.Count
			//	IWin32Window owner;

			//if (Application.OpenForms.Count != 0)
			//  owner = Application.OpenForms[0];
			//else
			//  owner = null;



			//MessageBox.Show(owner, "New releases are available: please update manually your repository", Properties.Settings.Default.ShellHome, MessageBoxButtons.OK, MessageBoxIcon.Warning);
		}
	}
}